<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Hello Trae</title>
    <meta name="description" content="一个现代、精美、交互性强的 Hello Trae 示例页面" />
    <style>
      :root {
        --bg: #0f172a; /* slate-900 */
        --surface: rgba(255, 255, 255, 0.08);
        --text: #e2e8f0; /* slate-200 */
        --muted: #94a3b8; /* slate-400 */
        --primary-1: #7c3aed; /* violet-600 */
        --primary-2: #06b6d4; /* cyan-500 */
        --accent: #22d3ee; /* cyan-400 */
        --ring: rgba(124, 58, 237, 0.35);
        --shadow: rgba(2, 6, 23, 0.6);
      }

      [data-theme="dark"] {
        --bg: #0b1020;
        --surface: rgba(255, 255, 255, 0.06);
        --text: #e5edf7;
        --muted: #95a4b8;
        --primary-1: #8b5cf6;
        --primary-2: #14b8a6;
        --accent: #60a5fa;
        --ring: rgba(96, 165, 250, 0.35);
        --shadow: rgba(0, 0, 0, 0.55);
      }

      /* 全局布局 */
      html, body {
        height: 100%;
      }
      body {
        margin: 0;
        font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
        color: var(--text);
        background: radial-gradient(1200px 600px at 20% 10%, rgba(124,58,237,.25), transparent 70%),
                    radial-gradient(1000px 500px at 80% 90%, rgba(6,182,212,.2), transparent 65%),
                    linear-gradient(180deg, #0b1220 0%, var(--bg) 100%);
        overflow: hidden;
      }

      .app {
        position: relative;
        min-height: 100vh;
        display: grid;
        place-items: center;
        padding: 24px;
      }

      /* 背景粒子画布 */
      canvas#bg {
        position: fixed;
        inset: 0;
        width: 100vw;
        height: 100vh;
        pointer-events: none;
        filter: blur(0.2px) saturate(110%);
        opacity: 0.6;
      }

      /* 漂浮装饰 */
      .blob {
        position: absolute;
        width: clamp(280px, 22vw, 380px);
        height: clamp(280px, 22vw, 380px);
        background: conic-gradient(from 0deg, var(--primary-1), var(--primary-2), var(--accent), var(--primary-1));
        filter: blur(32px);
        border-radius: 50%;
        opacity: 0.22;
        animation: float 18s ease-in-out infinite;
        will-change: transform;
      }
      .blob.b1 { top: 8%; left: 6%; animation-delay: -4s; }
      .blob.b2 { bottom: 12%; right: 8%; animation-delay: -10s; }

      @keyframes float {
        0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
        50%      { transform: translate3d(20px, -14px, 0) scale(1.06); }
      }

      /* 主卡片 */
      .card {
        position: relative;
        width: min(960px, 94vw);
        border-radius: 20px;
        background: linear-gradient(180deg, rgba(255,255,255,0.09), rgba(255,255,255,0.06));
        box-shadow: 0 30px 80px var(--shadow);
        backdrop-filter: saturate(140%) blur(14px);
        -webkit-backdrop-filter: saturate(140%) blur(14px);
        border: 1px solid rgba(255, 255, 255, 0.12);
        overflow: hidden;
        transition: transform 300ms ease, box-shadow 300ms ease;
      }
      .card:hover { transform: translateY(-2px); box-shadow: 0 40px 110px var(--shadow); }

      .inner {
        display: grid;
        grid-template-columns: 1fr;
        gap: 22px;
        padding: clamp(22px, 4vw, 40px);
      }

      .subtitle {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        color: var(--muted);
        font-size: clamp(13px, 2.4vw, 14px);
        letter-spacing: 0.2px;
        text-transform: uppercase;
      }
      .subtitle .dot {
        width: 8px; height: 8px; border-radius: 50%;
        background: radial-gradient(circle, var(--accent) 0%, transparent 66%);
        box-shadow: 0 0 20px var(--accent);
      }

      h1.title {
        margin: 0;
        font-size: clamp(36px, 8vw, 78px);
        line-height: 1.05;
        letter-spacing: -0.02em;
        background: linear-gradient(90deg, var(--primary-1), var(--accent), var(--primary-2));
        background-clip: text;
        -webkit-background-clip: text;
        color: transparent;
        text-shadow: 0 0 1px rgba(255,255,255,0.02);
        animation: shift 8s ease-in-out infinite;
      }
      @keyframes shift {
        0%, 100% { filter: hue-rotate(0deg) saturate(110%); }
        50%      { filter: hue-rotate(10deg) saturate(130%); }
      }

      p.desc {
        margin: 2px 0 12px;
        font-size: clamp(14px, 3.4vw, 18px);
        color: var(--muted);
      }

      .actions {
        display: flex;
        flex-wrap: wrap;
        gap: 12px;
        margin-top: 10px;
      }

      .btn {
        position: relative;
        display: inline-flex;
        align-items: center;
        gap: 10px;
        padding: 12px 18px;
        border-radius: 12px;
        border: 1px solid rgba(255,255,255,0.16);
        background: linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.08));
        color: var(--text);
        font-size: 15px;
        cursor: pointer;
        transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
        box-shadow: 0 8px 22px rgba(2, 8, 23, 0.45);
        outline: none;
        user-select: none;
        -webkit-tap-highlight-color: transparent;
      }
      .btn:hover { transform: translateY(-1px); border-color: rgba(255,255,255,0.24); }
      .btn:active { transform: translateY(0px) scale(0.99); }
      .btn:focus-visible { box-shadow: 0 0 0 6px var(--ring); }

      .btn.primary {
        background: linear-gradient(90deg, rgba(124,58,237,0.65), rgba(6,182,212,0.65));
        border-color: rgba(255,255,255,0.18);
      }

      .btn .icon {
        width: 18px; height: 18px;
        border-radius: 4px;
        background: radial-gradient(circle at 30% 30%, #fff, rgba(255,255,255,0.4) 40%, transparent 70%),
                    linear-gradient(90deg, var(--primary-1), var(--primary-2));
        box-shadow: inset 0 0 0 1px rgba(255,255,255,0.2);
      }

      /* 涟漪效果 */
      .ripple {
        position: absolute;
        border-radius: 50%;
        transform: translate(-50%, -50%);
        pointer-events: none;
        width: 8px; height: 8px;
        background: radial-gradient(circle, rgba(255,255,255,0.9), rgba(255,255,255,0.2) 60%, transparent 70%);
        animation: ripple 650ms ease-out;
        opacity: 0.7;
      }
      @keyframes ripple { from { width: 8px; height: 8px; opacity: 0.9; } to { width: 240px; height: 240px; opacity: 0; } }

      /* 页脚提示 */
      .hint {
        display: flex;
        align-items: center;
        gap: 8px;
        color: var(--muted);
        font-size: 13px;
        margin-top: 8px;
      }

      /* 渐入动画容器 */
      .reveal {
        opacity: 0; transform: translateY(12px);
        animation: reveal 680ms ease forwards;
      }
      .reveal.delay-1 { animation-delay: 120ms; }
      .reveal.delay-2 { animation-delay: 240ms; }
      .reveal.delay-3 { animation-delay: 360ms; }
      @keyframes reveal { to { opacity: 1; transform: none; } }

      /* 响应式微调 */
      @media (max-width: 560px) {
        .actions { gap: 10px; }
        .btn { width: 100%; justify-content: center; }
      }

      /* 降低运动偏好支持 */
      @media (prefers-reduced-motion: reduce) {
        * { animation: none !important; transition: none !important; }
      }
    </style>
  </head>
  <body>
    <canvas id="bg"></canvas>
    <div class="app">
      <div class="blob b1" aria-hidden="true"></div>
      <div class="blob b2" aria-hidden="true"></div>

      <section class="card" id="card" aria-label="Hello Trae 欢迎卡片">
        <div class="inner">
          <div class="subtitle reveal">
            <span class="dot" aria-hidden="true"></span>
            <span>欢迎来到你的 AI 开发工作流</span>
          </div>

          <h1 class="title reveal delay-1">Hello, Trae</h1>
          <p class="desc reveal delay-2">超轻量、现代、互动的示例页面。响应式、流畅动画与直观交互，助你快速上手。</p>

          <div class="actions reveal delay-3">
            <button class="btn primary" id="demoBtn" aria-label="交互演示">
              <span class="icon" aria-hidden="true"></span>
              <span>交互演示</span>
            </button>
            <button class="btn" id="themeBtn" aria-label="切换主题">
              <span class="icon" aria-hidden="true"></span>
              <span>切换主题</span>
            </button>
          </div>

          <div class="hint reveal delay-3" role="note">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
              <path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span>键盘快捷键：按 <strong>T</strong> 切换主题，按 <strong>R</strong> 查看涟漪效果。</span>
          </div>
        </div>
      </section>
    </div>

    <script>
      // 主题切换与持久化
      (function theme() {
        const root = document.documentElement;
        const saved = localStorage.getItem('hello-trae-theme');
        if (saved) root.setAttribute('data-theme', saved);
        const btn = document.getElementById('themeBtn');
        const toggle = () => {
          const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
          root.setAttribute('data-theme', next);
          localStorage.setItem('hello-trae-theme', next);
          sparkle(btn);
        };
        btn.addEventListener('click', (e) => {
          ripple(e, btn);
          toggle();
        });
        window.addEventListener('keydown', (e) => {
          if (e.key.toLowerCase() === 't') toggle();
        });
      })();

      // 涟漪效果（按钮点击反馈）
      function ripple(event, el) {
        const rect = el.getBoundingClientRect();
        const span = document.createElement('span');
        span.className = 'ripple';
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;
        span.style.left = x + 'px';
        span.style.top = y + 'px';
        el.appendChild(span);
        span.addEventListener('animationend', () => span.remove());
      }

      // 轻量闪烁粒子（按钮周围微交互）
      function sparkle(el) {
        const count = 10;
        const rect = el.getBoundingClientRect();
        for (let i = 0; i < count; i++) {
          const s = document.createElement('span');
          s.style.position = 'fixed';
          s.style.left = (rect.left + rect.width / 2) + 'px';
          s.style.top = (rect.top + rect.height / 2) + 'px';
          s.style.width = '4px';
          s.style.height = '4px';
          s.style.borderRadius = '50%';
          s.style.background = 'radial-gradient(circle, #fff, transparent 60%)';
          s.style.pointerEvents = 'none';
          const dx = (Math.random() - 0.5) * 160;
          const dy = (Math.random() - 0.5) * 160;
          const duration = 450 + Math.random() * 350;
          s.style.transition = `transform ${duration}ms ease, opacity ${duration}ms ease`;
          document.body.appendChild(s);
          requestAnimationFrame(() => {
            s.style.transform = `translate(${dx}px, ${dy}px)`;
            s.style.opacity = '0';
          });
          setTimeout(() => s.remove(), duration + 40);
        }
      }

      // 交互演示：卡片轻微 3D 倾斜 + 闪烁
      (function demo() {
        const card = document.getElementById('card');
        const btn = document.getElementById('demoBtn');
        let active = true;
        const tilt = (e) => {
          if (!active) return;
          const rect = card.getBoundingClientRect();
          const cx = e.clientX - rect.left;
          const cy = e.clientY - rect.top;
          const rx = ((cy / rect.height) - 0.5) * -6;
          const ry = ((cx / rect.width) - 0.5) * 6;
          card.style.transform = `perspective(900px) rotateX(${rx}deg) rotateY(${ry}deg)`;
        };
        const reset = () => {
          card.style.transform = '';
        };
        card.addEventListener('mousemove', tilt);
        card.addEventListener('mouseleave', reset);

        btn.addEventListener('click', (e) => {
          ripple(e, btn);
          active = !active;
          sparkle(btn);
          if (!active) { reset(); }
          btn.querySelector('span:last-child').textContent = active ? '交互演示' : '暂停演示';
        });

        window.addEventListener('keydown', (e) => {
          if (e.key.toLowerCase() === 'r') ripple({ clientX: window.innerWidth/2, clientY: window.innerHeight/2 }, btn);
        });
      })();

      // 背景轻量粒子动画（性能友好）
      (function particles() {
        const canvas = document.getElementById('bg');
        const ctx = canvas.getContext('2d');
        let dpr = Math.max(1, window.devicePixelRatio || 1);
        let width = 0, height = 0;
        const particles = [];
        const COUNT = 64;
        function resize() {
          width = canvas.clientWidth;
          height = canvas.clientHeight;
          canvas.width = Math.floor(width * dpr);
          canvas.height = Math.floor(height * dpr);
          ctx.scale(dpr, dpr);
        }
        function init() {
          particles.length = 0;
          for (let i = 0; i < COUNT; i++) {
            particles.push({
              x: Math.random() * width,
              y: Math.random() * height,
              vx: (Math.random() - 0.5) * 0.6,
              vy: (Math.random() - 0.5) * 0.6,
              r: 0.6 + Math.random() * 1.6,
              a: 0.35 + Math.random() * 0.4,
            });
          }
        }
        let mx = width/2, my = height/2;
        window.addEventListener('mousemove', (e) => { mx = e.clientX; my = e.clientY; });
        function step() {
          ctx.clearRect(0, 0, width, height);
          for (const p of particles) {
            p.x += p.vx + (mx - width/2) * 0.0006;
            p.y += p.vy + (my - height/2) * 0.0006;
            if (p.x < -10) p.x = width + 10; if (p.x > width + 10) p.x = -10;
            if (p.y < -10) p.y = height + 10; if (p.y > height + 10) p.y = -10;
            ctx.beginPath();
            ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
            ctx.fillStyle = `rgba(96, 165, 250, ${p.a})`;
            ctx.fill();
          }
          requestAnimationFrame(step);
        }
        resize(); init(); step();
        window.addEventListener('resize', () => { resize(); init(); });
      })();
    </script>
  </body>
  </html>